#include "socket.h"
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

TcpServer s;

void parentExit(int sig) {
    signal(SIGINT, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    std::cout << "parent exit: " << sig << std::endl;
    kill(0, SIGTERM);
    s.closeListen();
    exit(0);    
}

void childExit(int sig) {
    signal(SIGINT, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    std::cout << "child exit: " << sig << std::endl;
    s.closeClient();
    exit(0);
}

void closeAllSignal() {
    for (int i = 1; i <= 64; i ++) signal(i, SIG_IGN);
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        std::cerr << "usage: %s <port>" << std::endl;
    }

    closeAllSignal();
    signal(SIGTERM, parentExit);
    signal(SIGINT, parentExit);

    s = TcpServer();
    std::string buffer;

    if (!s.serverInit(atoi(argv[1]))) {
        std::cerr << "server init failed" << std::endl;
        return -1;
    }

    while (true) {
        std::cout << "Waiting for client connection..." << std::endl;
        
        if (!s.accept()) {
            std::cerr << "Server accept failed, retrying..." << std::endl;
            sleep(1);
            continue;
        }

        pid_t pid = fork();
        if (pid < 0) {
            std::cerr << "Fork failed: " << std::endl;
            s.closeClient();
            continue;
        } else if (pid == 0) {
            s.closeListen();
            signal(SIGTERM, childExit);
            signal(SIGINT, SIG_IGN);

            bool clientConnected = true;
            while (clientConnected) {
                if (s.recv(buffer, 512)) {
                    std::cout << "Received from client: " << buffer << std::endl;
                    
                    if (!s.send(buffer)) {
                        std::cerr << "Failed to send response to client" << std::endl;
                        clientConnected = false;
                    }
                    
                    buffer.clear();
                } else {
                    clientConnected = false;
                }
            }
            s.closeClient();
            exit(0);
        } else {
            s.closeClient();
        }
    }
    
    s.closeListen();
    return 0;
}